<?php

declare(strict_types=1);

namespace App\CustHub\Model;

use App\Common\Constants\ErrorCode;
use App\CustHub\Service\ChConfigService;
use App\CustHub\Service\CommonService;
use App\Enum\WordTypeEnum;
use App\Exception\BusinessException;
use Hyperf\DbConnection\Db;
use Mine\MineModel;
use function Hyperf\Collection\data_get;

/**
 * @property int $id 主键
 * @property int $main_uid 主账号id
 * @property int $uid 私域用户ID
 * @property int $is_star 是否标星
 * @property string $title 标题
 * @property int $is_personal 1个人 2企业
 * @property string $msg_types 包含的类型
 * @property \Carbon\Carbon $created_at 
 * @property \Carbon\Carbon $updated_at 
 * @property int $is_important 
 * @property int $robot_id 收录机器人
 * @property-read mixed $content 内容
 * @property-read mixed $tags 
 */
class ChMaterial extends MineModel
{
    /**
     * The table associated with the model.
     */
    protected ?string $table = 'ch_material';

    /**
     * The attributes that are mass assignable.
     */
    protected array $fillable = ['id', 'main_uid', 'uid', 'is_star', 'title', 'content', 'is_personal', 'msg_types', 'created_at', 'updated_at', 'is_important', 'robot_id'];

    /**
     * The attributes that should be cast to native types.
     */
    protected array $casts = ['id' => 'integer', 'main_uid' => 'integer', 'uid' => 'integer', 'is_star' => 'integer', 'content' => 'array', 'is_personal' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime', 'is_important' => 'integer', 'robot_id' => 'integer'];


    public static $limit = 1000;
    public static $enterpriseLimit = 2000;

    public function getContentAttribute()
    {
        return !empty($this->attributes['content'])?json_decode($this->attributes['content'],true):[];
    }

    public function getTagsAttribute()
    {
        $tags = [];
        $materialId = $this -> attributes['id'];
        if($materialId){
            $tags =  Db::table('ch_material_to_tag as tt') -> leftJoin('ch_material_tag as t','tt.tag_id','=','t.id')
                -> where('tt.material_id',$materialId) -> whereNotNull('t.id') ->  get(["t.id","t.name"]);
        }
        return $tags;
    }
    public static function  saveMaterial($uid,$mainUid,$data = [],$id = 0)
    {

        $model = Db::transaction(function() use ($uid,$id,$data,$mainUid){
            $model = new self();
            if($id){
                $model = self::where('id',$id) -> first();
                if(empty($model)) throw new BusinessException(ErrorCode::NOT_ISSET,'数据不存在');
            }
            $model -> uid = $uid;
            $model -> title = $data['title'];
            $model -> robot_id = !empty($data['robot_id'])?$data['robot_id']:0;
            if(!is_array($data['content'])){
                $data['content'] = json_decode($data['content'],true);
            }
            $info = CommonService::formatMsgContent($data['content']);
//            if($id==0 && $info['msg_types']==WordTypeEnum::MINI_PROGRAM){
//                $appid=$info['content'][0]['content']['appid'];
//                $material=self::where('uid',$uid)->whereRaw("JSON_SEARCH(content, 'one', ?) IS NOT NULL", [$appid])->first();
//                if(!empty($material)) return $material;
//            }
//            if($id==0 && $info['msg_types']==WordTypeEnum::VIDEO_CHANNEL){
//                $channelUrl=$info['content'][0]['content']['channel_url'];
//                $material=self::where('uid',$uid)->whereRaw("JSON_SEARCH(content, 'one', ?) IS NOT NULL", [$channelUrl])->first();
//                if(!empty($material)) return $material;
//            }
            $model -> content = $info['content'];
            $model -> is_important = data_get($data,'is_important',0);
            $model -> msg_types = $info['msg_types'];
            $model -> is_personal = $data['is_personal'];
            $model -> main_uid = $mainUid;
            $model -> save();
            //绑定标签关系
            !empty($data['tags']) && ChMaterialToTag::bindTags($data['tags'],$model -> id);
            //删除最早的10条数据
            self::clearMaterial($uid,$mainUid,$data['is_personal']);
            return $model;
        });
        return $model;
    }

    public static function clearMaterial($uid,$mainUid,$isPersonal=0)
    {
        if($isPersonal){
            //个人收录配置
            $material_collect_person_config = container()->get(ChConfigService::class)->getConfigByGroupKey($uid,$mainUid,'material_collect_person_config');
            if(!empty($material_collect_person_config['material_collect_person_config']['value'])){
                $cfg=json_decode($material_collect_person_config['material_collect_person_config']['value'],true);
                $is_clear=!empty($cfg['is_clear'])?1:0;
                if($is_clear){
                    $not_clear_important=!empty($cfg['not_clear_important'])?1:0;
                    $where=[
                        'main_uid'=>$mainUid,
                        'uid'=>$uid,
                        'is_personal'=>1
                    ];
                    if(self::where($where)->count() > self::$limit){
                        $query=self::where($where);
                        $not_clear_important && $query->where('is_important','<>',1);
                        $query->orderBy('id','asc')->limit(10)->delete();
                    }
                }
            }
        }else{
            //企业收录配置
            $material_collect_enterprise_config = container()->get(ChConfigService::class)->getConfigByGroupKey($uid,$mainUid,'material_collect_config');
            if(!empty($material_collect_enterprise_config['material_collect_enterprise_config']['value'])){
                $cfg=json_decode($material_collect_enterprise_config['material_collect_enterprise_config']['value'] ,true);
                $is_clear=!empty($cfg['is_clear'])?1:0  ;
                if($is_clear){
                    $not_clear_important=!empty($cfg['not_clear_important'])?1:0;
                    $where=[
                        'main_uid'=>$mainUid,
                        'is_personal'=>0
                    ];
                    if(self::where($where)->count() > self::$enterpriseLimit){
                        $query=self::where($where);
                        $not_clear_important && $query->where('is_important','<>',1);
                        $query->orderBy('id','asc')->limit(10)->delete();
                    }
                }
            }
        }
    }

}
